package com.photoeditor.demo.ui.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

import com.photoeditor.R;


/**
 * 自己实现的一个类似seekbar的控件,区别是中间的图和进度条分开
 * 中间可以使用透明图以实现透明效果
 * xml属性可以指定left_bar, right_bar, thumb 等属性
 * 使用时需要指定该控件高度,不然可能会占据整个父控件
 * <p>
 * 可以指定方向，竖直只使用一个背景 left_bar
 */
public class MySeekBar extends View {

    private GestureDetector mGestureDetector;
    private SeekBarGestureListener mGestureListener;
    private int mHeight;
    private int mWidth;

    private Bitmap mThumbBitmap = null;
    private Bitmap mLeftBarBitmap = null;
    private Bitmap mRightBarBitmap = null;
    private Rect mLeftSrcRect = null;
    private Rect mRightSrcRect = null;
    private Paint mPaint = null;
    private boolean mIsTouch = false;
    public static final int HORIZONTAL = 0;
    public static final int VERTICAL = 1;
    private int mOrientation;
    private Drawable mLeftDrawable;

    public MySeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    public MySeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    private void getAttrs(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MySeekBar);
        mOrientation = typedArray.getInt(R.styleable.MySeekBar_bar_orientation, HORIZONTAL);
        int resId = typedArray.getResourceId(R.styleable.MySeekBar_thumb, 0);
        mThumbBitmap = BitmapFactory.decodeResource(getResources(), resId);
        resId = typedArray.getResourceId(R.styleable.MySeekBar_left_bar, 0);
        mLeftDrawable = getResources().getDrawable(resId);
        mLeftBarBitmap = BitmapFactory.decodeResource(getResources(), resId);
        mLeftSrcRect = new Rect(0, 0, mLeftBarBitmap.getWidth(), mLeftBarBitmap.getHeight());
        resId = typedArray.getResourceId(R.styleable.MySeekBar_right_bar, 0);
        mRightBarBitmap = BitmapFactory.decodeResource(getResources(), resId);
        mRightSrcRect = new Rect(0, 0, mRightBarBitmap.getWidth(), mRightBarBitmap.getHeight());
        typedArray.recycle();


    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (mOrientation == VERTICAL) {
            mLeftDrawable.setBounds(w / 2 - mLeftBarBitmap.getWidth() / 2, 0, w / 2 + mLeftBarBitmap.getWidth() / 2, h);
            mOffset = h - mThumbBitmap.getHeight();
        }
    }

    private void init(Context context, AttributeSet attrs) {
        getAttrs(context, attrs);
        mPaint = new Paint();
        mGestureListener = new SeekBarGestureListener();
        mGestureDetector = new GestureDetector(context, mGestureListener);
    }

    private int mOffset = 0;
    private OnSeekBarChangeListener mOnSeekBarChangeListener = null;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (mOrientation == HORIZONTAL) {
                updateOffset(event.getX());
            } else {
                updateOffset(event.getY());
            }
            mIsTouch = false;
            return true;
        }
        return mGestureDetector.onTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save();
        Rect rect = canvas.getClipBounds();
        mHeight = rect.height();
        mWidth = rect.width();
        int thumbWidth = mThumbBitmap.getWidth();
        int thumbHeight = mThumbBitmap.getHeight();
        if (mOrientation == HORIZONTAL) {
            int barWidth = mLeftBarBitmap.getHeight();
            Rect leftRect = new Rect(0 + rect.left, mHeight / 2 - barWidth / 2 + rect.top, mOffset + rect.left, mHeight / 2 + barWidth / 2 + rect.top);
            Rect rightRect = new Rect(mOffset + thumbWidth + rect.left, mHeight / 2 - barWidth / 2 + rect.top, mWidth + rect.left, mHeight / 2 + barWidth / 2 + rect.top);
            canvas.drawBitmap(mLeftBarBitmap, mLeftSrcRect, leftRect, mPaint);
            canvas.drawBitmap(mRightBarBitmap, mRightSrcRect, rightRect, mPaint);
            canvas.drawBitmap(mThumbBitmap, mOffset + rect.left, mHeight / 2 - thumbHeight / 2 + rect.top, mPaint);
        } else if (mOrientation == VERTICAL) {
            //int barWidth = mLeftBarBitmap.getWidth();
            //Rect leftRect = new Rect(rect.left + mWidth / 2 - barWidth / 2, rect.top, rect.left + mWidth / 2 + barWidth / 2,rect.bottom);
            //Rect rightRect = new Rect(rect.left + mWidth / 2 - barWidth / 2, rect.top + mOffset + thumbHeight, rect.left + mWidth / 2 + barWidth / 2, rect.top + mHeight);
            //canvas.drawBitmap(mLeftBarBitmap, mLeftSrcRect, leftRect, mPaint);
            //canvas.drawBitmap(mRightBarBitmap, mRightSrcRect, rightRect, mPaint);
            mLeftDrawable.draw(canvas);
            canvas.drawBitmap(mThumbBitmap, rect.left + mWidth / 2 - thumbWidth / 2, rect.top + mOffset, mPaint);
        }
        canvas.restore();
    }

    public void setOnSeekBarChangeListener(OnSeekBarChangeListener listener) {
        mOnSeekBarChangeListener = listener;
    }

    private void updateOffset(float offset) {
        mOffset = (int) offset;
        if (mOffset < 0)
            mOffset = 0;
        int maxValue = 0;
        if (mOrientation == HORIZONTAL) {
            maxValue = mWidth - mThumbBitmap.getWidth();
        } else if (mOrientation == VERTICAL) {
            maxValue = mHeight - mThumbBitmap.getHeight();
        }
        if (mOffset > maxValue) {
            mOffset = maxValue;
        }
        invalidate();
        if (mOnSeekBarChangeListener != null) {
            mOnSeekBarChangeListener.onSeekBarChanged(1 - (float) mOffset / maxValue);
        }

    }

    public void updateOffsetByPercent(float percent) {
        float maxValue = 0;
        if (mOrientation == HORIZONTAL) {
            maxValue = mWidth - mThumbBitmap.getWidth();
            mOffset = (int) (percent * maxValue);
        } else if (mOrientation == VERTICAL) {
            maxValue = mHeight - mThumbBitmap.getHeight();
            mOffset = (int) (maxValue - percent * maxValue);
        }
        invalidate();
    }

    private class SeekBarGestureListener extends
            GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                float distanceX, float distanceY) {
            if (mOrientation == HORIZONTAL) {
                updateOffset(e2.getX());
            } else if (mOrientation == VERTICAL) {
                updateOffset(e2.getY());
            }
            return true;
        }

        @Override
        public boolean onDown(MotionEvent e) {
            mIsTouch = true;
            return true;
        }
    }

    public interface OnSeekBarChangeListener {
        public void onSeekBarChanged(float percent);
    }

    public boolean isTouch() {
        return mIsTouch;
    }
}